#include "client.h"
#include "message.h"
#include "user.h"
#include <string.h>

void CreateUser(User * NewUser)
{
	SetUserName(NewUser, CreateUserName());
	SetCSock(NewUser, CreateSocket());
	SetSin(NewUser, CreateSin());
}

char * CreateUserName()
{
	char * userName = (char*)malloc(30*sizeof(char));
	printf("\nChoisissez votre pseudo : ");
	fgets(userName, 30, stdin);
    clean(userName);
	return userName;
}

SOCKET CreateSocket()
{
    return socket(AF_INET, SOCK_STREAM, 0);
}

SOCKADDR_IN CreateSin()
{
    SOCKADDR_IN sin;
    char IP[20];

    printf("Veuillez entrer l'IP du serveur : ");
	fgets(IP, sizeof IP, stdin);
    clean(IP);

    sin.sin_addr.s_addr = inet_addr(IP);
    sin.sin_family = AF_INET;
    sin.sin_port = htons(PORT);

    return sin;
}

/* Retourne 0 pour erreur, 1 pour connecté. */
int Connection(User NewUser)
{
	SOCKET csock = GetCSock(NewUser);
	SOCKADDR_IN sin = GetSin(NewUser);
	int Connected;
	
	if (connect(csock, (SOCKADDR*)&sin, sizeof(sin)) == SOCKET_ERROR)
	{
		Connected = 0;
	}
	else
	{
		Connected = 1;
	}

	return Connected;
}

/* Dans l'interface graphique, il faudra bloquer la saisie */
/* à 200 caractères !!! */
void * SendMessage(void * ptr_abstract)
{
	while(1)
	{
		/* Déclarations */
		Message NewMessage;
		char * string = (char*)malloc(200*sizeof(char));
		size_t len;
	
		/* Recupération de infos du client passées en param */
		User NewUser = *((User*)ptr_abstract);
		SOCKET csock = GetCSock(NewUser);
		
		assert( csock != INVALID_SOCKET );
		
		printf("%s : ", GetUserName(NewUser));
		fflush(stdout);

		fgets(string, 200, stdin);
    	clean(string);
   	 	len = strlen(string);
		SetUser(&NewMessage, &NewUser);
		assert( send(csock, &len, sizeof(len), 0) != SOCKET_ERROR );
		assert( send(csock, string, len, 0) != SOCKET_ERROR );
		assert( send(csock, &NewMessage, sizeof(Message), 0) != SOCKET_ERROR );
		free(string);
	}
}

void * ReceiveMessage(void * ptr_abstract)
{
	SOCKET sock = ((User*)ptr_abstract)->sock;
	while(1)
	{
		size_t lenUserName, lenString;
		char * userName, * string;
		
		assert( sock != INVALID_SOCKET );
		getchar();
		/* On récupère le pseudo de l'auteur du message */
		assert( recv(sock, &lenUserName, sizeof(lenUserName), 0) != SOCKET_ERROR );
		userName = (char*)malloc(lenUserName*sizeof(char));
		assert( recv(sock, userName, lenUserName, 0) != SOCKET_ERROR );
		
		/* On récupère le message */
		assert( recv(sock, &lenString, sizeof(lenString), 0) != SOCKET_ERROR );
		string = (char*)malloc(lenString*sizeof(char));
		assert( recv(sock, string, lenString, 0) != SOCKET_ERROR );
		printf("\n%s : %s", userName, string);
		fflush(stdout);
		free(userName);
		free(string);
	}
}

void SendUser(User * NewUser)
{
	size_t len = strlen(NewUser->userName);
	assert( send(GetCSock(*NewUser), &len, sizeof(len), 0) != SOCKET_ERROR );
	assert( send(GetCSock(*NewUser), GetUserName(*NewUser), len, 0) != SOCKET_ERROR );
	assert( send(GetCSock(*NewUser), NewUser, sizeof(User), 0) != SOCKET_ERROR );
}


static void purger(void)
{
    int c;
 
    while ((c = getchar()) != '\n' && c != EOF)
    {}
}

static void clean (char *chaine)
{
    char *p = strchr(chaine, '\n');
 
    if (p)
    {
        *p = 0;
    }
 
    else
    {
        purger();
    }
}
